	//////////////////////////////////////////////////////
	//					GENERAL NOTES					//
	//////////////////////////////////////////////////////
	/*
	 **PreFix TS - Stands for Temperature Sensor 
	 * Apply to All variables  Due To Similar Names on Imu9DOFDriver
	 * 
	 * */
		 #include "DS16XXDriver.h"
/******************************************************************************
*   Type Definitions
******************************************************************************/
	enum 
	{
		STATE0=0,
		STATE1,
		STATE2,
		STATE3,
		STATE4,
		MAXSTATE
	};
	
	enum 
	{
		STATE_I=0,	//State Start Conversion
		STATE_R,	//State read Temperature
		STATE_S,	//State Stops Conversion
		MAXSTATE_TS
	};
	
/******************************************************************************
*   						EXTERNAL VARIABLES
******************************************************************************/
	DS16XXTemp DS1624Temp;		//Variable where Temperature is locatated
	
/******************************************************************************
*   					LOCAL VARIABLE DEFINITIONS
******************************************************************************/
	SMts TSSendRequest;			//State machine status to send Command and data
	SMts TSSendCommand;			//State machine status to send a single Command
	SMts TSReadData;			//State machine status to read data
	SMts TempSensorRead;		//State machine status of whole process to read data
	
	/* 
	 **PreFix TS - Stands for Temperature Sensor */
	volatile unsigned char TSHighData,TSLowData;						//16bits Data receive from Temperature Sensor
	volatile unsigned char TSSensor,TSRegisterAddress,TSDataToSend;
	
/******************************************************************************
*   					LOCAL FUNCTIONS PROTOTYPES
******************************************************************************/
	// Function to setup I2C module and Temperature sensor	//
	void VfnI2CSetupTS(void);
	// Function pointer to a state of the machine "Send Data"	//
	void (* const TSSendDataI2C[])(void);
	// Function pointer to a state of the machine "Send Command"	//
	void (* const TSSendCommandI2C[])(void);
	// Function pointer to a state of the machine "REad Data"	//
	void (* const TSReadDataI2C[])(void);
		
/******************************************************************************
*   					GLOBAL FUNCTIONS DEFINITIONS
******************************************************************************/
/*****************************************************************************
 * Function: 	VfnDS16XXSensorInitialization
 * Description: Setup I2C Module, Initiate State Machines for read and write. 
 * 				And configurate the Temperature Sensor MODE.
 * Caveats:
 * Parameters:	Mode - configuration mode of the sensor
 * Return:     
 *****************************************************************************/	
	void VfnDS16XXSensorInitialization(char Mode)
	{
		/* Initiate I2C port 
		 * Prepare State Machines /to send and receive data
		 * Configurate Temperature Sensor -> Mode
		 */
		TSSendRequest.ActualState = STATE0;
		TSReadData.ActualState = STATE0;
		TSSendCommand.ActualState = STATE0;
		TempSensorRead.ActualState = STATE_I;
		VfnI2CSetupTS();
			
		//If mode is on ONE SHOT MODE is true, setup.	//
		if( Mode == ONE_SHOT_MODE)	
		{
			TSSensor = DS16XX_ADDRESS;					//Temperature sensor Address
    		TSRegisterAddress = ACCESS_CONFIG;			//Configuration address
    		TSDataToSend = 0x01;						//Data
    		TSSendRequest.ActualState = STATE0;			//Initiate State
    		while(TSSendRequest.ActualState != MAXSTATE)
    		{
   				TSSendDataI2C[TSSendRequest.ActualState]();
    		}
		}
		if( Mode == CONTINUOUS_MODE)
		{
			TSSensor = DS16XX_ADDRESS;					//Temperature sensor Address
    		TSRegisterAddress = ACCESS_CONFIG;			//Configuration address			
    		TSDataToSend = 0x00;						//Data
    		TSSendRequest.ActualState = STATE0;			//Initiate State
    		while(TSSendRequest.ActualState != MAXSTATE)
    		{
   				TSSendDataI2C[TSSendRequest.ActualState]();
    		}
		}
		// After This section code and procede to read the sensor
		// No further accesses to the DS16XX should be made for at least 10ms
	}

/*****************************************************************************
 * Function: 	VfnDS16XXSensorDriver
 * Description: Read Temperature Sensor base on the Mode configuration.
 * 				One shot 	- Start convertion
 * 						 	- Read Temperature
 * 						 	- Stop Convertion
 * 				Continuos	- Read Temperature
 * Caveats:
 * Parameters:	Mode - configuration mode of the sensor
 * Return:      1 when Read is done.
 *****************************************************************************/		
	char VfnDS16XXSensorDriver(char Mode)
	{
		/* Depends on Mode Operation 
		 * 
		 */
		char ReadDone;
		ReadDone = 0;
		if( Mode == ONE_SHOT_MODE)
		{
			//Star convertion by sending command START CONVERT T
			//Send ""single"" Command State Machine running 
			if(TempSensorRead.ActualState == STATE_I)		
			{
				TSSensor = DS16XX_ADDRESS;
    			TSRegisterAddress = START_CONVERT_T;				
    			TSSendCommandI2C[TSSendCommand.ActualState]();
				if(TSSendCommand.ActualState == MAXSTATE)
				{
					TSSendCommand.ActualState = STATE0;
					TempSensorRead.ActualState = STATE_R;
				}
			}
			//Star convertion by sending command READ TEMPERATURE
			//Read data State MAchine running
			if(TempSensorRead.ActualState == STATE_R)		
			{
				TSSensor = DS16XX_ADDRESS;
    			TSRegisterAddress = READ_TEMPERATURE;
				TSReadDataI2C[TSReadData.ActualState]();
				if(TSReadData.ActualState == MAXSTATE)
				{
					TSReadData.ActualState = STATE0;
					TempSensorRead.ActualState = STATE_I;
					ReadDone = 1;
				}
			}
		}
		if( Mode == CONTINUOUS_MODE)
		{
			TSSensor = DS16XX_ADDRESS;
    		TSRegisterAddress = READ_TEMPERATURE;
			TSReadDataI2C[TSReadData.ActualState]();
			if(TSReadData.ActualState == MAXSTATE)
			{
				TSReadData.ActualState = STATE0;
				ReadDone = 1;
			}
		}
		
		return ReadDone;	
	}
	
/*****************************************************************************
 * Function: 	VfnDS16XXTemperatureToString
 * Description: Function that return the Temperature into a string.
 * Caveats:
 * Parameters:	String where temperature is storage, Temperature 
 * Return:      
 *****************************************************************************/	
	void VfnDS16XXTemperatureToString(char* String,DS16XXTemp Temperature)
	{
		volatile short Decimal;
		volatile short OneUnit,TenUnit,HundredUnit,ThousandUnit;
		if(Temperature.WholeTemperature >= 0)
		{
			*String = '+';
			String++;
			*String = (Temperature.WholeTemperature / 100) + 48;	
			String++;
			*String = (Temperature.WholeTemperature / 10) + 48;	
			String++; 
			*String = (Temperature.WholeTemperature-((Temperature.WholeTemperature/10)*10)) + 48;
			String++;
			*String = '.';
			String++;
			
			Temperature.DecimalTemperature = Temperature.DecimalTemperature>>4;
			Decimal = 0;
			if(((Temperature.DecimalTemperature) & 0x01)==1)
	  		{
	   			Decimal=625;
	  		}
			if(((Temperature.DecimalTemperature) & 0x02)==2)
	  		{
	  			 Decimal+=1250;
	  		}
			if(((Temperature.DecimalTemperature) & 0x04)==4)
	  		{
	  			 Decimal+=2500;
	  		}
			if(((Temperature.DecimalTemperature) & 0x08)==8)
	  		{
	  			 Decimal+=5000;
	  		}
			if(((Temperature.DecimalTemperature) & 0x0F)==0)
	  		{
	  			 Decimal+=0;
	  		}
			
			ThousandUnit = ( Decimal / 1000);
			HundredUnit  = ((Decimal-((Decimal/1000)*1000)))/100;
			TenUnit      = ( Decimal-((ThousandUnit*1000)+(HundredUnit*100)))/10;
			OneUnit      = ( Decimal-((ThousandUnit*1000)+(HundredUnit*100)+(TenUnit*10)));
			*String = ThousandUnit + 48;
			String++;
			*String = HundredUnit + 48;
			String++;
			*String = TenUnit + 48;
			String++;
			*String = OneUnit + 48;
		}
		else
		{
			
		}
	}
	
/******************************************************************************
*   					LOCAL FUNCTIONS DEFINITIONS
******************************************************************************/
/*****************************************************************************
 * Function: 	VfnI2CSetupTS
 * Description: Setup I2C Module.
 * Caveats:
 * Parameters:	 
 * Return:      
 *****************************************************************************/	
	void VfnI2CSetupTS(void)
	{
		//////////////////////////////////////////////
		//		I2C MODULE CONFIGURATION			//
		//////////////////////////////////////////////
		#if (I2C_MODULE_TS == I2C0)
		SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);					//Clock to I2C0 module
		SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);				//clock to PORTB module
		GPIOPinTypeI2C( GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3 );	//I2C's pins configuration
		
			#if I2C_FREQ == I2C_400K
    			I2CMasterInitExpClk(I2C0_MASTER_BASE, SysCtlClockGet(), true);	//I2C frequency at 400khz
			#endif
			#if I2C_FREQ == I2C_100K
				I2CMasterInitExpClk(I2C0_MASTER_BASE, SysCtlClockGet(), false);	//I2C frequency at 100khz
			#endif
			
    	I2CMasterEnable( I2C0_MASTER_BASE );
		#endif
		#if (I2C_MODULE_TS == I2C1)
		SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);					//Clock to I2C1 module
		SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);				//clock to PORTA module
		GPIOPinTypeI2C( GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7 );	//I2C's pins configurations
		
			#if I2C_FREQ == I2C_400K
    			I2CMasterInitExpClk(I2C1_MASTER_BASE, SysCtlClockGet(), true);	//I2C frequency at 400khz
			#endif
			#if I2C_FREQ == I2C_100K
				I2CMasterInitExpClk(I2C1_MASTER_BASE, SysCtlClockGet(), false);	//I2C frequency at 100khz
			#endif	
			
    	I2CMasterEnable( I2C1_MASTER_BASE );
		#endif	
	}

		
	//////////////////////////////////////////////
	//		STATE MACHINE TO SEND DATA I2C		//
	//////////////////////////////////////////////
/*****************************************************************************
 * Function: 	VfnTSSendDataState0
 * Description: Write address and data to send via I2C.
 * Caveats:
 * Parameters:	 
 * Return:      
 *****************************************************************************/
	void VfnTSSendDataState0 (void)
	{
		#if (I2C_MODULE_TS == I2C0)
		I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, TSSensor, false);
    	I2CMasterDataPut(I2C0_MASTER_BASE, TSRegisterAddress	 );							
		I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);
		#endif
		#if (I2C_MODULE_TS == I2C1)
		I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, TSSensor, false);
    	I2CMasterDataPut(I2C1_MASTER_BASE, TSRegisterAddress	 );							
		I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);
		#endif
		TSSendRequest.ActualState = STATE3;
		TSSendRequest.NextState   = STATE1;
	}
/*****************************************************************************
 * Function: 	VfnTSSendDataState1
 * Description: I2C Command to send address and data.
 * Caveats:
 * Parameters:	 
 * Return:      
 *****************************************************************************/
	void VfnTSSendDataState1 (void)
	{
		#if (I2C_MODULE_TS == I2C0)
		I2CMasterDataPut(I2C0_MASTER_BASE, TSDataToSend);
		#endif
		#if (I2C_MODULE_TS == I2C1)
		I2CMasterDataPut(I2C1_MASTER_BASE, TSDataToSend);
		#endif
		TSSendRequest.ActualState = STATE3;
		TSSendRequest.NextState   = STATE2;
	}
	
/*****************************************************************************
 * Function: 	VfnTSSendDataState2
 * Description: I2C command to finish the transmission.
 * Caveats:
 * Parameters:	 
 * Return:      
 *****************************************************************************/
	void VfnTSSendDataState2 (void)
	{
		#if (I2C_MODULE_TS == I2C0)
		I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
		#endif
		#if (I2C_MODULE_TS == I2C1)
		I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
		#endif
		TSSendRequest.ActualState = STATE3;
		TSSendRequest.NextState   = MAXSTATE;
	}

/*****************************************************************************
 * Function: 	VfnTSSendDataState3
 * Description: check if I2C module is busy, if not jump to next state.
 * Caveats:
 * Parameters:	 
 * Return:      
 *****************************************************************************/
	void VfnTSSendDataState3 (void)
	{
		#if (I2C_MODULE_TS == I2C0)
		if(!(I2CMasterBusy(I2C0_MASTER_BASE)))
		{
			TSSendRequest.ActualState = TSSendRequest.NextState;
		}
		#endif
		#if (I2C_MODULE_TS == I2C1)
		if(!(I2CMasterBusy(I2C1_MASTER_BASE)))
		{
			TSSendRequest.ActualState = TSSendRequest.NextState;
		}
		#endif
	}

/*****************************************************************************
 * Function: 	void (* const TSSendDataI2C[])(void)
 * Description: Functions pointer array. representing each state.
 * Caveats:
 * Parameters:	 
 * Return:      
 *****************************************************************************/	
	void (* const TSSendDataI2C[])(void)	=
	{
		VfnTSSendDataState0,
		VfnTSSendDataState1,
		VfnTSSendDataState2,
		VfnTSSendDataState3,
	};
	
	//////////////////////////////////////////////
	//		STATE MACHINE TO SENDS COMMAND		//
	//////////////////////////////////////////////
/*****************************************************************************
 * Function: 	VfnTSSendCommandState0
 * Description: write address and command to send bye the I2C module to slave.
 * 				single command.
 * Caveats:
 * Parameters:	 
 * Return:      
 *****************************************************************************/
	void VfnTSSendCommandState0 (void)
	{
		#if (I2C_MODULE_TS == I2C0)
		I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, TSSensor, false);
    	I2CMasterDataPut(I2C0_MASTER_BASE, TSRegisterAddress	 );							
		I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_SINGLE_SEND );
		#endif
		#if (I2C_MODULE_TS == I2C1)
		I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, TSSensor, false);
    	I2CMasterDataPut(I2C1_MASTER_BASE, TSRegisterAddress	 );							
		I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_SINGLE_SEND );
		#endif
		TSSendCommand.ActualState = STATE1;
		TSSendCommand.NextState   = MAXSTATE;
	}

/*****************************************************************************
 * Function: 	VfnTSSendCommandState1
 * Description: Check if I2C module is busy, if not jump to next state.
 * Caveats:
 * Parameters:	 
 * Return:      
 *****************************************************************************/
	void VfnTSSendCommandState1 (void)
	{
		#if (I2C_MODULE_TS == I2C0)
		if(!(I2CMasterBusy(I2C0_MASTER_BASE)))
		{
			TSSendCommand.ActualState = TSSendCommand.NextState;
		}
		#endif
		#if (I2C_MODULE_TS == I2C1)
		if(!(I2CMasterBusy(I2C1_MASTER_BASE)))
		{
			TSSendCommand.ActualState = TSSendCommand.NextState;
		}
		#endif
	}
/*****************************************************************************
 * Function: 	void (* const TSSendCommandI2C[])(void)
 * Description: Functions pointer array. representing each state.
 * Caveats:
 * Parameters:	 
 * Return:      
 *****************************************************************************/	
	void (* const TSSendCommandI2C[])(void)	=
	{
		VfnTSSendCommandState0,
		VfnTSSendCommandState1,
	};
	
	
	//////////////////////////////////////////////
	//		STATE MACHINE TO READ DATA I2C		//
	//////////////////////////////////////////////
	// State 0 - Send Sensor Address and command //
/*****************************************************************************
 * Function: 	VfnTSReadDataState0
 * Description: Write address and data to I2C module to be send it.
 * Caveats:
 * Parameters:	 
 * Return:      
 *****************************************************************************/	
	void VfnTSReadDataState0 (void)
	{
		#if (I2C_MODULE_TS == I2C0)
		I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, TSSensor, false);
   		I2CMasterDataPut(I2C0_MASTER_BASE, TSRegisterAddress);
		I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_SINGLE_SEND );
		#endif
		#if (I2C_MODULE_TS == I2C1)
		I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, TSSensor, false);
   		I2CMasterDataPut(I2C1_MASTER_BASE, TSRegisterAddress);
		I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_SINGLE_SEND );
		#endif
		TSReadData.ActualState = STATE4;
		TSReadData.NextState   = STATE1;
	}
/*****************************************************************************
 * Function: 	VfnTSReadDataState1
 * Description: I2C module sends Restart to slave.
 * Caveats:
 * Parameters:	 
 * Return:      
 *****************************************************************************/	
	void VfnTSReadDataState1 (void)
	{
		#if (I2C_MODULE_TS == I2C0)
		I2CMasterSlaveAddrSet(I2C0_MASTER_BASE,TSSensor, true);
		I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START );
		#endif
		#if (I2C_MODULE_TS == I2C1)
		I2CMasterSlaveAddrSet(I2C1_MASTER_BASE,TSSensor, true);
		I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START );
		#endif
		TSReadData.ActualState = STATE4;
		TSReadData.NextState   = STATE2;
	}
/*****************************************************************************
 * Function: 	VfnTSReadDataState2
 * Description: Receive the first byte of data "Whole Temperature" and send ACK 
 * 				and prepar to finish reading.
 * Caveats:
 * Parameters:	 
 * Return:      
 *****************************************************************************/	
	void VfnTSReadDataState2 (void)
	{
		#if (I2C_MODULE_TS == I2C0)
		TSHighData= I2CMasterDataGet(I2C0_MASTER_BASE);
		I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH  );
		#endif
		#if (I2C_MODULE_TS == I2C1)
		TSHighData= I2CMasterDataGet(I2C1_MASTER_BASE);
		I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH  );
		#endif
		
			DS1624Temp.WholeTemperature = TSHighData;
			
		TSReadData.ActualState = STATE4;
		TSReadData.NextState   = STATE3;
	}
/*****************************************************************************
 * Function: 	VfnTSReadDataState3
 * Description: State 3 - Receive the second byte of data "Decimal Temperature" 
 * 				and don't send ACK "Finish I2C reading" 
 * Caveats:
 * Parameters:	 
 * Return:      
 *****************************************************************************/
	void VfnTSReadDataState3 (void)
	{
		#if (I2C_MODULE_TS == I2C0)
		TSLowData= (I2CMasterDataGet(I2C0_MASTER_BASE));
		#endif
		#if (I2C_MODULE_TS == I2C1)
		TSLowData= (I2CMasterDataGet(I2C1_MASTER_BASE));
		#endif
			
			DS1624Temp.DecimalTemperature = TSLowData;
			
		TSReadData.ActualState = STATE4;
		TSReadData.NextState   = MAXSTATE;
	}
/*****************************************************************************
 * Function: 	VfnTSReadDataState4
 * Description: State4 "Common State" wait for I2C Module to be Ready
 * Caveats:
 * Parameters:	 
 * Return:      
 *****************************************************************************/
	void VfnTSReadDataState4 (void)
	{
		#if (I2C_MODULE_TS == I2C0)
		if(!(I2CMasterBusy(I2C0_MASTER_BASE)))
		{
			TSReadData.ActualState = TSReadData.NextState;
		}
		#endif
		#if (I2C_MODULE_TS == I2C1)
		if(!(I2CMasterBusy(I2C1_MASTER_BASE)))
		{
			TSReadData.ActualState = TSReadData.NextState;
		}
		#endif
	}

/*****************************************************************************
 * Function: 	void (* const TSReadDataI2C[])(void)
 * Description: Functions pointer array. representing each state.
 * Caveats:
 * Parameters:	 
 * Return:      
 *****************************************************************************/	
	void (* const TSReadDataI2C[])(void)	=
	{
		VfnTSReadDataState0,
		VfnTSReadDataState1,
		VfnTSReadDataState2,
		VfnTSReadDataState3,
		VfnTSReadDataState4,
	};
